﻿namespace zijian666.DI;
internal class OnceCaller
{
    public static Task ExecuteAsync(ref Task? token, Func<Task> action)
    {
        if (token is not null || action is null)
        {
            return token ?? Task.CompletedTask;
        }
        var source = new TaskCompletionSource();
        var task = Interlocked.CompareExchange(ref token, source.Task, null);
        if (task is not null)
        {
            return task;
        }
        action().ContinueWith(t =>
        {
            if (t.IsFaulted)
            {
                source.TrySetException(t.Exception!.InnerExceptions);
            }
            else if (t.IsCanceled)
            {
                source.TrySetCanceled();
            }
            else
            {
                source.TrySetResult();
            }
        });
        return source.Task;
    }
}
